<script lang="ts" setup>
import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { ElInput, ElLoading } from "element-plus";
import { Position } from "@element-plus/icons-vue";
import card from "./component/card.vue";
import cardEditor from "./component/card-editor.vue";
import { avators, role } from "./index"; // 导入avators
import * as markedLib from "marked";
const { marked } = markedLib;

// 添加防抖和节流工具函数
const debounce = (fn: Function, delay: number) => {
  let timer: number | null = null;
  return function (this: any, ...args: any[]) {
    if (timer) clearTimeout(timer);
    timer = window.setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  };
};

const throttle = (fn: Function, delay: number) => {
  let lastCall = 0;
  return function (this: any, ...args: any[]) {
    const now = Date.now();
    if (now - lastCall >= delay) {
      fn.apply(this, args);
      lastCall = now;
    }
  };
};

interface ThinkItem {
  id: number | string;
  think: string;
  [key: string]: any;
}

interface leftInfo {
  id: number | string;
  user: string;
  thinkLists: ThinkItem[];
}

// 定义WebSocket连接地址
const socket = ref();
// 存储接收到的消息
let times = ref(0);
const cardEditorRef = ref();

const searchForValue = ref(""); // 搜索框
const selectId = ref();
const leftDialogList = ref<leftInfo[]>([]);
const rightAnwerList = ref<any>([]);
const dataBase: any = ref([]);

// 输入框的显示隐藏
const inputShow = ref(false); // 默认设为不可输入

// 添加工程师角色定义
const engineerRoles = [
  { id: 1, name: "业务分析师" },
  { id: 2, name: "数据分析师" },
  { id: 3, name: "测试工程师" },
  { id: 4, name: "结论" },
];

// 获取工程师名称的函数
const getEngineerName = (id: string | number) => {
  const engineer = engineerRoles.find((role) => role.id == id);
  return engineer ? engineer.name : "思考";
};

// 新建会话
const addSession = () => {
  // 在新标签页打开首页
  window.open(import.meta.env.BASE_URL, '_blank');
};

// 检查折叠
const checkFold = (val: boolean) => {
  cardEditorRef.value.topFold = !val; // 将折叠状态传递给 card-editor 组件
};

// 文字打印机效果
const index = ref(0);
const displayText = ref("");
const printLetter = () => {
  if (index.value < searchForValue.value.length) {
    displayText.value += searchForValue.value[index.value];
    index.value++;

    leftDialogList.value[leftDialogList.value.length - 1].user =
      displayText.value;
    setTimeout(printLetter, 100);
  }
};

// 添加重连相关变量
const isReconnecting = ref(false);
const reconnectAttempts = ref(0);
const maxReconnectAttempts = 5;
const reconnectInterval = 3000; // 3秒

// 添加消息队列
const messageQueue = ref<any[]>([]);
const isProcessingQueue = ref(false);

// 添加消息批处理配置
const batchSize = 5; // 每批处理的消息数量
const processingDelay = 10; // 批处理间隔(毫秒)
const updateUIThreshold = 3; // 处理多少条消息后更新UI

// 全局变量，用于跟踪当前处理的工程师ID
let currentEngineerId: string | number | null = null;
let thinks: ThinkItem[] = [];
let answers: any = [];

// 添加页面加载状态
const pageLoading = ref(true);
const loadingInstance = ref<null | {
  close: () => void;
  setText: (text: string) => void;
}>(null);

// 在script部分添加折叠状态管理
const foldedMessages = ref<Record<string, boolean>>({});

// 切换折叠状态的函数
const toggleFold = (messageId: string) => {
  foldedMessages.value[messageId] = !foldedMessages.value[messageId];
};

// 判断消息是否需要折叠
const shouldFoldMessage = (content: string) => {
  return content && content.length > 500; // 超过500个字符的消息可以折叠
};

// 获取折叠后的消息预览，显示最新内容
const getFoldedPreview = (content: string) => {
  if (!content || content.length <= 500) return content;

  // 显示最新的300个字符
  const latestContent = content.substring(content.length - 300);
  // 添加省略号表示前面有更多内容
  return '...' + latestContent;
};

// 添加性能监控
let lastUIUpdateTime = Date.now();
let messagesProcessedSinceLastUpdate = 0;
let pendingUIUpdate = false;

// 优化后的处理消息队列函数
const processMessageQueue = async () => {
  if (isProcessingQueue.value || messageQueue.value.length === 0) return;

  isProcessingQueue.value = true;

  // 使用setTimeout创建宏任务，避免长时间阻塞主线程
  const processBatch = () => {
    const batchEnd = Math.min(batchSize, messageQueue.value.length);
    let updateUI = false;

    if (batchEnd <= 0) {
      isProcessingQueue.value = false;
      return;
    }

    // 处理当前批次的消息
    for (let i = 0; i < batchEnd; i++) {
      const message = messageQueue.value.shift();
      processMessage(message);

      messagesProcessedSinceLastUpdate++;

      // 判断是否需要更新UI
      if (messagesProcessedSinceLastUpdate >= updateUIThreshold) {
        updateUI = true;
      }
    }

    // 如果需要更新UI或队列已清空
    if (updateUI || messageQueue.value.length === 0) {
      if (!pendingUIUpdate) {
        pendingUIUpdate = true;
        // 使用requestAnimationFrame确保在下一帧渲染前更新UI
        window.requestAnimationFrame(() => {
          nextTick(() => {
            scrollToBottom();
            messagesProcessedSinceLastUpdate = 0;
            lastUIUpdateTime = Date.now();
            pendingUIUpdate = false;
          });
        });
      }
    }

    // 继续处理队列中的下一批消息或结束处理
    if (messageQueue.value.length > 0) {
      setTimeout(processBatch, processingDelay);
    } else {
      isProcessingQueue.value = false;
    }
  };

  processBatch();
};

// 使用缓存优化Markdown渲染
const markdownCache = new Map();
const renderMarkdown = (content: string): string => {
  if (!content) return "";

  // 检查缓存中是否已有渲染结果
  if (markdownCache.has(content)) {
    return markdownCache.get(content);
  }

  try {
    // 强制将返回类型转为string
    const result = marked.parse(content);
    let context = typeof result === "string" ? result : String(result);
    context = context.replaceAll("<p>", "<span>").replaceAll("</p>", "</span>");

    if (context.includes('<code')) {
      // 缓存结果
      markdownCache.set(content, context);
      return context;
    }

    const finalResult = context.replaceAll('\n', '');
    // 缓存结果
    markdownCache.set(content, finalResult);
    return finalResult;
  } catch (error) {
    console.error("Markdown渲染错误:", error);
    return content;
  }
};

// 修改 WebSocket 消息接收处理
const handleWebSocketMessage = (event: any) => {
  if (!!event.data) {
    try {
      const parsedData = JSON.parse(event.data);

      // 优先检查用户接受状态
      if (parsedData?.user?.accept === true) {
        console.log("收到用户接受消息，启用输入框");
        inputShow.value = true;
      }

      // 检查是否包含数据库结构信息，如果有，优先处理
      if (parsedData?.database) {
        processDataBaseStructure(parsedData);
      }

      // 如果只包含用户接受状态而没有数据库信息，直接返回
      if (parsedData?.user?.accept === true && !parsedData?.database && !parsedData?.engineer) {
        return;
      }

      // 将其他消息添加到队列
      if (parsedData?.engineer) {
        messageQueue.value.push(parsedData);

        // 开始处理队列
        if (!isProcessingQueue.value) {
          processMessageQueue();
        }
      }
    } catch (error) {
      console.error("解析WebSocket消息时出错:", error);
    }
  }
};

// 单独处理数据库结构信息的函数
const processDataBaseStructure = (parsedData: any) => {
  try {
    const userDatabase = parsedData?.database;

    if (!!userDatabase) {
      console.log("收到数据库结构信息:", userDatabase);
      const keys = Object.keys(userDatabase);
      dataBase.value = keys.map((item: any) => {
        const columns = Object.keys(userDatabase[item]?.columns || {});
        return {
          label: item,
          children: columns.map((columnName: any) => {
            return { label: columnName };
          }),
        };
      });

      // 注意：输入框状态现在由handleWebSocketMessage中的user.accept处理

      // 确保立即更新UI
      nextTick(() => {
        // 如果有cardEditor组件，更新它的值
        if (cardEditorRef.value) {
          cardEditorRef.value.userDatabase = dataBase.value;
        }
      });
    }
  } catch (error) {
    console.error("处理数据库结构时出错:", error);
  }
};

// 修改处理单个消息的函数，移除冗余的user.accept检查
const processMessage = (parsedData: any) => {
  try {
    // 检查是否为数据库结构信息
    if (parsedData?.database) {
      processDataBaseStructure(parsedData);
      return;
    }

    // TODO
    if (!!searchForValue.value) {
      // 收到其他消息时，禁用输入框
      inputShow.value = false;
      const data = parsedData?.engineer;

      if (!data) {
        console.log("没有工程师数据");
        return;
      }

      // 设置当前选中的工程师ID
      if (!!data && data.id != 4) selectId.value = data.id;

      // 处理结论数据 (id=4)
      if (!!data && data.id == 4) {
        const existingIndex = answers.findIndex(
          (item: any) => item.id == data.id
        );

        if (existingIndex != -1) {
          const updatedAnswer = {
            ...answers[existingIndex],
            answer: (answers[existingIndex].answer || "") + (data.answer || ""),
          };
          answers[existingIndex] = updatedAnswer;
        } else {
          answers.push({ ...data });
        }

        // 确保数组索引有效
        const l = Math.max(0, leftDialogList.value.length - 1);
        rightAnwerList.value[l] = [...answers];

        // 更新编辑器的值
        if (cardEditorRef.value) {
          cardEditorRef.value.editorPromptValue = [...rightAnwerList.value];
        }

        // 重置answers数组，但保持thinks数组不变
        answers = [];
      } else if (!!data && data.hasOwnProperty("answer")) {
        // 处理普通回答数据
        const existingIndex = answers.findIndex(
          (item: any) => item.id == data.id
        );

        if (existingIndex != -1) {
          answers[existingIndex] = {
            ...answers[existingIndex],
            answer: (answers[existingIndex].answer || "") + (data.answer || ""),
          };
        } else {
          answers.push({ ...data });
        }

        // 确保数组索引有效
        const l = Math.max(0, leftDialogList.value.length - 1);
        rightAnwerList.value[l] = [...answers];

        // 更新编辑器的值
        if (cardEditorRef.value) {
          cardEditorRef.value.editorPromptValue = [...rightAnwerList.value];
        }
      } else if (!!data && data.hasOwnProperty("think")) {
        // 处理思考数据 - 优化版本
        processThinkMessage(data);
      } else {
        console.log("未知数据类型:", data);
      }
    }
  } catch (error) {
    console.error("处理消息时出错:", error);
  }
};

// 处理思考消息的函数
const processThinkMessage = (data: any) => {
  try {
    if (currentEngineerId !== data.id) {
      // 角色变化，创建新消息
      const messageId = `${data.id}-${new Date().getTime()}`;
      thinks.push({
        ...data,
        think: data.think || "",
        timestamp: new Date().getTime(),
      });

      // 默认设置长消息为展开状态
      if (shouldFoldMessage(data.think || "")) {
        foldedMessages.value[messageId] = true;
      }

      currentEngineerId = data.id;
    } else {
      // 同一角色连续消息，尝试合并
      const lastIndex = thinks.length - 1;

      if (lastIndex >= 0 && thinks[lastIndex].id == data.id) {
        // 内容可接受，追加到现有消息
        thinks[lastIndex] = {
          ...thinks[lastIndex],
          think: (thinks[lastIndex].think || "") + (data.think || ""),
        };

        // 检查合并后是否需要折叠
        const messageId = `${thinks[lastIndex].id}-${thinks[lastIndex].timestamp}`;
        if (shouldFoldMessage(thinks[lastIndex].think) && foldedMessages.value[messageId] === undefined) {
          foldedMessages.value[messageId] = true;
        }
      } else {
        // 找不到匹配项，创建新消息
        const messageId = `${data.id}-${new Date().getTime()}`;
        thinks.push({
          ...data,
          think: data.think || "",
          timestamp: new Date().getTime(),
        });

        // 默认设置长消息为展开状态
        if (shouldFoldMessage(data.think || "")) {
          foldedMessages.value[messageId] = true;
        }
      }
    }

    // 确保对话列表已初始化
    if (!leftDialogList.value.length) {
      leftDialogList.value[0] = {
        id: times.value,
        user: "",
        thinkLists: [],
      };
    }

    // 更新思考列表
    const currentIndex = Math.max(0, leftDialogList.value.length - 1);
    leftDialogList.value[currentIndex] = {
      ...leftDialogList.value[currentIndex],
      thinkLists: [...thinks],
    };
  } catch (error) {
    console.error("处理思考消息时出错:", error);
  }
};

// 优化的滚动到底部函数
const scrollToBottom = throttle(() => {
  const dialogContainer = document.querySelector(".add-dialog");
  if (dialogContainer) {
    dialogContainer.scrollTop = dialogContainer.scrollHeight;
  }
}, 200); // 每200ms最多滚动一次

// 修改 WebSocket 初始化函数
const initWebSocket = () => {
  // 显示全屏加载
  loadingInstance.value = ElLoading.service({
    lock: true,
    text: "正在连接服务器...",
    background: "rgba(255, 255, 255, 0.8)",
  }) as { close: () => void; setText: (text: string) => void };

  const connect = () => {
    try {
      const ws_url = "ws://localhost:8765";
      //const ws_url = "ws://" + window.location.host + "/ws";
      socket.value = new WebSocket(ws_url);

      socket.value.onopen = () => {
        console.log("WebSocket 连接已建立");
        isReconnecting.value = false;
        reconnectAttempts.value = 0;

        // 关闭加载状态
        if (loadingInstance.value) {
          loadingInstance.value.close();
          loadingInstance.value = null;
        }
        pageLoading.value = false;
      };

      // 接收到消息时触发
      socket.value.onmessage = handleWebSocketMessage;

      socket.value.onclose = (event: CloseEvent) => {
        console.log("WebSocket 连接已关闭", event);
        inputShow.value = true;
        searchForValue.value = "";

        // 如果是首次加载失败，显示错误信息
        if (pageLoading.value) {
          if (loadingInstance.value) {
            loadingInstance.value.close();
            loadingInstance.value = null;
          }

          // 显示连接失败的提示
          ElLoading.service({
            lock: true,
            text: "连接服务器失败，请刷新页面重试",
            background: "rgba(255, 255, 255, 0.8)",
          });

          return;
        }

        // 非正常关闭且不是正在重连时尝试重连
        if (
          !event.wasClean &&
          !isReconnecting.value &&
          reconnectAttempts.value < maxReconnectAttempts
        ) {
          isReconnecting.value = true;
          reconnectAttempts.value++;
          console.log(
            `尝试重连 (${reconnectAttempts.value}/${maxReconnectAttempts})...`
          );

          // 显示重连中的加载状态
          loadingInstance.value = ElLoading.service({
            lock: true,
            text: `正在重新连接服务器 (${reconnectAttempts.value}/${maxReconnectAttempts})...`,
            background: "rgba(255, 255, 255, 0.8)",
          }) as { close: () => void; setText: (text: string) => void };

          setTimeout(connect, reconnectInterval);
        }
      };

      // 连接出错时触发
      socket.value.onerror = (error: any) => {
        console.error("WebSocket 连接出错:", error);
      };
    } catch (error) {
      console.error("创建 WebSocket 连接时出错:", error);

      // 连接失败时尝试重连
      if (
        !isReconnecting.value &&
        reconnectAttempts.value < maxReconnectAttempts
      ) {
        isReconnecting.value = true;
        reconnectAttempts.value++;
        console.log(
          `连接失败，尝试重连 (${reconnectAttempts.value}/${maxReconnectAttempts})...`
        );

        // 更新加载状态文本
        if (loadingInstance.value) {
          loadingInstance.value.setText(
            `正在重新连接服务器 (${reconnectAttempts.value}/${maxReconnectAttempts})...`
          );
        }

        setTimeout(connect, reconnectInterval);
      } else {
        // 达到最大重连次数，显示错误信息
        if (loadingInstance.value) {
          loadingInstance.value.close();
          loadingInstance.value = null;
        }

        // 显示连接失败的提示
        ElLoading.service({
          lock: true,
          text: "连接服务器失败，请刷新页面重试",
          background: "rgba(255, 255, 255, 0.8)",
        });
      }
    }
  };

  connect();
};

// 发送消息到服务器
const changeForValue = () => {
  if (!searchForValue.value.trim() || !inputShow.value) return; // 添加输入框状态检查

  index.value = 0;
  displayText.value = "";

  // 添加新的用户消息到对话列表
  leftDialogList.value.push({
    id: times.value,
    user: "",
    thinkLists: [],
  });

  times.value++;
  printLetter();

  if (socket.value && socket.value.readyState === WebSocket.OPEN) {
    socket.value.send(
      JSON.stringify({
        user: {
          input: searchForValue.value,
        },
      })
    );
  }

  // 发送消息后禁用输入框
  inputShow.value = false;

  // 重置当前工程师ID，以便下一次对话正确创建新的思考项
  currentEngineerId = null;
  // 仅重置思考列表，便于新对话的处理
  thinks = [];

  // 清空消息缓存，避免缓存过大
  if (markdownCache.size > 100) {
    markdownCache.clear();
  }
};

// 添加退出登录功能
const logout = () => {
  localStorage.removeItem('isLoggedIn');
  window.location.href = import.meta.env.BASE_URL + 'login';
};

onMounted(() => {
  initWebSocket();

  // 添加性能监控
  if (process.env.NODE_ENV === 'development') {
    window.addEventListener('beforeunload', () => {
      console.log('缓存大小:', markdownCache.size);
    });
  }
});

onUnmounted(() => {
  if (socket.value) {
    socket.value.close();
  }

  // 确保关闭加载状态
  if (loadingInstance.value) {
    loadingInstance.value.close();
    loadingInstance.value = null;
  }

  // 清空缓存
  markdownCache.clear();
});
</script>

<template>
  <div class="body-container">
    <div class="w-420px h-full body-left relative">
      <div class="flex items-center justify-between">
        <div class="flex items-center">
          <span class="font-bold lette-spacing-1px">数据洞察</span>
          <span class="add-button m-l-24px bg-#eeeeef border-rd-4px color-#989899 flex items-center cursor-pointer"
            style="font-size: 11px; padding: 1px 6px" @click="addSession"><img src="../../assets/images/add.png"
              width="12" height="12" class="m-r-4px" /><span>新建会话</span></span>
        </div>
        <el-button type="danger" size="small" @click="logout">退出登录</el-button>
      </div>
      <!--用户问题 -->
      <div v-if="leftDialogList" v-for="item in leftDialogList" :key="item.id">
        <div class="flex mb-24px flex-row-reverse" style="position: fixed; width: 420px;">
          <img src="../../assets/images/1414.jpg" width="30" height="30" class="ml-8px transparent-bg" />
          <!--  color-#8abd8a -->
          <div class="p-12px rd-4px w-100% bg-#e9f4e9">
            <div class="w-100%" style="
                  font-size: 12px;
                  border-bottom: 1px solid #8abd8a;
                  box-sizing: border-box;
                ">
              需求
            </div>
            <div ref="printText" class="text-reveal pt-8px pb-8px markdown-content"
              style="font-size: 12px; height: fit-content">
              {{ item.user }}
            </div>
          </div>
        </div>
      </div>
      <!--模型对话 -->
      <div style="font-family: 微软雅黑;margin-top: 100px;height: 86%"
        class="mt-32px overflow-y-scroll hid-scroll add-dialog">
        <div v-if="leftDialogList" v-for="item in leftDialogList" :key="item.id">
          <div v-for="els in item.thinkLists" :key="`${els.id}-${els.timestamp || ''}`" class="flex mb-24px">
            <img src="../../assets/images/1111.png" alt="" width="30" height="30" class="m-r-12px transparent-bg"
              v-if="els.id == 1" />
            <img src="../../assets/images/1212.png" alt="" width="30" height="30" class="m-r-12px transparent-bg"
              v-if="els.id == 2" />
            <img src="../../assets/images/1313.png" alt="" width="30" height="30" class="m-r-12px transparent-bg"
              v-if="els.id == 3" />

            <div class="p-8px rd-4px w-90%" :style="{
              boxSizing: 'border-box',
              background:
                els.id == '1'
                  ? '#e8daf4'
                  : els.id == '2'
                    ? '#e0f2fb'
                    : '#fffce2',
            }">
              <div class="w-100%" style="font-size: 12px" :style="{
                'border-bottom':
                  els.id == '1'
                    ? '1px solid #b77ddb'
                    : els.id == '2'
                      ? '1px solid #57b5e5'
                      : '1px solid #f5a853',
              }">
                {{ getEngineerName(els.id) }}
              </div>
              <div v-if="shouldFoldMessage(els.think)" class="pt-8px text-reveal markdown-content"
                style="font-size: 12px; width: 100%; word-break: break-word;">
                <div v-if="foldedMessages[`${els.id}-${els.timestamp}`]" v-html="renderMarkdown(els.think)"></div>
                <div v-else v-html="renderMarkdown(getFoldedPreview(els.think))"></div>
                <div class="fold-toggle" @click="toggleFold(`${els.id}-${els.timestamp}`)">
                  <span class="fold-text">{{ foldedMessages[`${els.id}-${els.timestamp}`] ? '收起' : '展开全部' }}</span>
                </div>
              </div>
              <div v-else ref="printText" class="pt-8px text-reveal markdown-content"
                style="font-size: 12px; height: fit-content; width: 100%; word-break: break-word;"
                v-html="renderMarkdown(els.think)"></div>
            </div>
          </div>
        </div>
      </div>

      <div class="absolute bottom-16px w-full flex items-center" style="width: 400px; position: fixed;">
        <el-input v-model="searchForValue" :disabled="!inputShow" @keyup.enter="changeForValue"
          :placeholder="inputShow ? '请输入您的问题...' : '等待系统响应...'" />
        <el-icon class="position right-30px" :class="{
          'cursor-pointer': inputShow,
          'cursor-not-allowed text-gray-400': !inputShow,
        }" @click="inputShow ? changeForValue() : null">
          <Position />
        </el-icon>
      </div>
    </div>
    <div class="body-right">
      <div>
        <card @checkFold="checkFold" :selectId="selectId"></card>
        <cardEditor ref="cardEditorRef" :selectId="selectId" :userDatabase="dataBase"></cardEditor>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.body-container {
  width: 100vw;
  height: 100vh;
  padding: 16px 32px;
  box-sizing: border-box;
  display: flex;

  .body-left {
    .add-button:hover {
      background: #ddd;
    }

    .hid-scroll {
      -ms-overflow-style: none;
      scrollbar-width: none;

      /* 显示滚动条 */
      &::-webkit-scrollbar {
        width: 6px;
        height: 6px;
        background-color: #f5f5f5;
      }

      &::-webkit-scrollbar-track {
        border-radius: 6px;
        background-color: #f5f5f5;
      }

      &::-webkit-scrollbar-thumb {
        border-radius: 6px;
        background-color: #aaa;

        &:hover {
          background-color: #888;
        }
      }
    }

    .text-reveal {
      font-family: monospace;
      white-space: pre-wrap;
      line-height: 1.5;
      overflow: hidden;
      animation: blink-caret 0.75s step-end infinite;
    }

    @keyframes blink-caret {

      from,
      to {
        border-color: transparent;
      }

      50% {
        border-color: orange;
      }
    }
  }

  .body-right {
    flex: 1;
    margin: 16px 0px 16px 16px;
    overflow: hidden;
  }
}

.transparent-bg {
  background-color: transparent !important;
  object-fit: contain;
}

/* 添加禁用状态样式 */
.cursor-not-allowed {
  cursor: not-allowed;
}

.text-gray-400 {
  color: #9ca3af;
}

/* 折叠按钮样式 */
.fold-toggle {
  margin-top: 8px;
  cursor: pointer;
  display: flex;
  justify-content: center;
}

.fold-text {
  padding: 2px 8px;
  background-color: #f3f4f6;
  border-radius: 4px;
  font-size: 12px;
  color: #6b7280;
}

.fold-text:hover {
  background-color: #e5e7eb;
  color: #374151;
}

/* Markdown样式 */
:deep(.markdown-content) {

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    margin-top: 8px;
    margin-bottom: 4px;
    font-weight: 600;
  }

  h1 {
    font-size: 1.4em;
  }

  h2 {
    font-size: 1.3em;
  }

  h3 {
    font-size: 1.2em;
  }

  p {
    margin: 0px;
  }

  ul,
  ol {
    padding-left: 20px;
    margin: 0px;

    li {
      margin: 0px;
      padding: 0px;
    }
  }

  code {
    background-color: rgba(0, 0, 0, 0.05);
    padding: 2px 4px;
    border-radius: 3px;
    font-family: monospace;
  }

  pre {
    background-color: rgba(0, 0, 0, 0.05);
    padding: 8px;
    border-radius: 4px;
    overflow-x: auto;
    margin: 8px 0;

    code {
      background-color: transparent;
      padding: 0;
    }
  }

  blockquote {
    border-left: 3px solid #d1d5db;
    padding-left: 8px;
    color: #6b7280;
    margin: 8px 0;
  }

  table {
    border-collapse: collapse;
    width: 100%;
    margin: 8px 0;

    th,
    td {
      border: 1px solid #d1d5db;
      padding: 4px 8px;
      text-align: left;
    }

    th {
      background-color: rgba(0, 0, 0, 0.05);
    }
  }

  a {
    color: #3b82f6;
    text-decoration: none;

    &:hover {
      text-decoration: underline;
    }
  }
}
</style>
